package com.huizhonglm.diap.ui.wallet;

import android.content.Intent;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.RadioButton;
import android.widget.RadioGroup;
import android.widget.Toast;

import com.alipay.sdk.app.PayTask;
import com.tencent.mm.sdk.constants.Build;
import com.tencent.mm.sdk.modelpay.PayReq;
import com.tencent.mm.sdk.openapi.IWXAPI;
import com.tencent.mm.sdk.openapi.WXAPIFactory;
import com.unionpay.UPPayAssistEx;
import com.bruce.common.utils.EmptyUtil;
import com.huizhonglm.diap.R;
import com.huizhonglm.diap.api.model.wallet.AliOrderResponse;
import com.huizhonglm.diap.api.model.wallet.RechargeParams;
import com.huizhonglm.diap.core.config.Constants;
import com.huizhonglm.diap.core.utils.DialogUtil;
import com.huizhonglm.diap.core.utils.LogUtil;
import com.huizhonglm.diap.core.utils.RSAUtil;
import com.huizhonglm.diap.core.utils.ToastUtil;
import com.huizhonglm.diap.core.utils.UserUtil;
import com.huizhonglm.diap.model.AliPayResult;
import com.huizhonglm.diap.presenters.wallet.RechargePresenter;
import com.huizhonglm.diap.ui.BaseActivity;
import com.huizhonglm.diap.ui.wallet.iView.RechargeIView;

import org.json.JSONException;
import org.json.JSONObject;

import java.io.ByteArrayOutputStream;
import java.io.InputStream;
import java.lang.ref.WeakReference;
import java.net.URL;
import java.net.URLConnection;

/**
 * 确认支付页面
 *
 * @author LiXiaoLong
 * @version 1.0
 * @since 2015-07-07 09:14
 */
public class RechargeActivity extends BaseActivity implements RechargeIView, View.OnClickListener,
        RadioGroup.OnCheckedChangeListener {
    private final int PAY_AL = 1;
    private final int PAY_WX = 2;
    private final int PAY_UP = 3;

    private final String PAY_METHOD_WX = "payByWeixin";
    private final String PAY_METHOD_AL = "payByzhifubao";
    private final String PAY_METHOD_UP = "payByUnion";
    private final String PAY_FAILURE = "failureToPay";
    private final String PAY_CANCEL = "cancelToPay";

    private EditText amountEdt;
    private Button rechargeBtn;

    private RechargePresenter mPresenter;
    private PayHandler mHandler;

    private String payMethod = PAY_METHOD_UP;

    /**
     * 银联支付【mMode参数解释： "00" - 启动银联正式环境 "01" - 连接银联测试环境】
     */
    private final String mMode = "01";
    private final String upPayURL = "http://101.231.204.84:8091/sim/getacptn";

    /**
     * 微信支付
     */
    private IWXAPI wxAPI;
    private final String wxPayURL = "http://wxpay.weixin.qq.com/pub_v2/app/app_pay.php?plat=android";

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_recharge);
        setBackEvent(this, null);
        wxAPI = WXAPIFactory.createWXAPI(this, Constants.WECHAT_APPID);
        mPresenter = new RechargePresenter(this);
        mHandler = new PayHandler(RechargeActivity.this);
        assignViews();
    }

    @Override
    protected void assignViews() {
        RadioGroup payRGP = (RadioGroup) findViewById(R.id.pay_method_rgp);
        RadioButton wxRbtn = (RadioButton) findViewById(R.id.pay_wx_rbtn);
        amountEdt = (EditText) findViewById(R.id.amount_edt);
        rechargeBtn = (Button) findViewById(R.id.recharge_btn);
        if (wxAPI.getWXAppSupportAPI() >= Build.PAY_SUPPORTED_SDK_INT) {
            wxRbtn.setVisibility(View.VISIBLE);
        } else {
            wxRbtn.setVisibility(View.GONE);
        }
        payRGP.setOnCheckedChangeListener(this);
        rechargeBtn.setOnClickListener(this);
    }

    @Override
    public void onClick(View v) {
        switch (v.getId()) {
            case R.id.recharge_btn:
                String amount = amountEdt.getText().toString().trim();
                if (EmptyUtil.isEmpty(amount)) {
                    ToastUtil.makeTextShort("请输入充值金额");
                    return;
                }
                Double totalFee = Double.valueOf(amount);
                rechargeBtn.setEnabled(false);
                switch (payMethod) {
                    case PAY_METHOD_UP:
                        upPay();
                        break;
                    case PAY_METHOD_WX:
                        wxPay();
                        break;
                    case PAY_METHOD_AL:
                        mPresenter.getAliOrderInfo(totalFee);
                        break;
                }
                break;
        }
    }

    @Override
    public void onCheckedChanged(RadioGroup group, int checkedId) {
        switch (checkedId) {
            case R.id.pay_up_rbtn:
                payMethod = PAY_METHOD_UP;
                break;
            case R.id.pay_wx_rbtn:
                payMethod = PAY_METHOD_WX;
                break;
            case R.id.pay_al_rbtn:
                payMethod = PAY_METHOD_AL;
                break;
        }
    }

    @Override
    public void getAliOrderSuccess(AliOrderResponse resp) {
        String orderInfo = resp.getOrderInfo();
        if (EmptyUtil.isEmpty(orderInfo)) {
            ToastUtil.makeTextShort("生成订单失败，请稍后重试");
        } else {
            alPay(orderInfo);
        }
    }

    @Override
    public void getAliOrderFailure() {
        ToastUtil.makeTextShort("生成订单失败，请稍后重试");
    }

    @Override
    public void onRechargeSuccess() {
        hideProgressBar();
        // TODO: 跳转到支付成功页面
        startActivity(new Intent(this, PaymentSuccessActivity.class));
        finish();
    }

    @Override
    public void onRechargeFailure(String errMsg) {
        hideProgressBar();
        DialogUtil.showConfirmDialog(this, "支付失败", "支付失败，点击确定重试。", new DialogUtil.OnDialogBtnClickListener() {
            @Override
            public void onBtnClick(String btnText) {
                onRecharge();
            }
        });
    }

    private void alPay(final String orderInfo) {
        try {
            // 完整的符合支付宝参数规范的订单信息
            Runnable alPayRun = new Runnable() {

                @Override
                public void run() {
                    // 构造PayTask 对象
                    PayTask alipay = new PayTask(RechargeActivity.this);
                    // 调用支付接口，获取支付结果
                    String result = alipay.pay(orderInfo, true);
                    Message msg = new Message();
                    msg.what = PAY_AL;
                    msg.obj = result;
                    mHandler.sendMessage(msg);
                }
            };
            // 必须异步调用
            new Thread(alPayRun).start();
        } catch (Exception e) {
            e.printStackTrace();
            rechargeBtn.setEnabled(true);
        }
    }

    private void upPay(){
        /**
         * 【银联支付】步骤1：从网络开始,获取交易流水号即TN
         */
        Runnable upPayRun = new Runnable() {
            @Override
            public void run() {
                String tn = null;
                InputStream is;
                try {
                    URL myURL = new URL(upPayURL);
                    URLConnection ucon = myURL.openConnection();
                    ucon.setConnectTimeout(120000);
                    is = ucon.getInputStream();
                    int i;
                    ByteArrayOutputStream baos = new ByteArrayOutputStream();
                    while ((i = is.read()) != -1) {
                        baos.write(i);
                    }
                    tn = baos.toString();
                    is.close();
                    baos.close();
                } catch (Exception e) {
                    e.printStackTrace();
                    rechargeBtn.setEnabled(true);
                }
                Message msg = mHandler.obtainMessage();
                msg.what = PAY_UP;
                msg.obj = tn;
                mHandler.sendMessage(msg);
            }
        };
        new Thread(upPayRun).start();
    }

    private void wxPay(){
        ToastUtil.makeTextShort("获取订单中...");
        Runnable wxPayRun = new Runnable() {
            @Override
            public void run() {
                String content = null;
                try{
                    URL myURL = new URL(wxPayURL);
                    URLConnection ucon = myURL.openConnection();
                    ucon.setConnectTimeout(120000);
                    InputStream is = ucon.getInputStream();
                    int i;
                    ByteArrayOutputStream baos = new ByteArrayOutputStream();
                    while ((i = is.read()) != -1) {
                        baos.write(i);
                    }
                    content = baos.toString();
                    is.close();
                    baos.close();
                }catch (Exception e) {
                    e.printStackTrace();
                    rechargeBtn.setEnabled(true);
                    LogUtil.error("PAY_GET", "异常："+e.getMessage());
                    ToastUtil.makeTextShort("异常："+e.getMessage());
                }
                Message msg = mHandler.obtainMessage();
                msg.what = PAY_WX;
                msg.obj = content;
                mHandler.sendMessage(msg);
            }
        };
        new Thread(wxPayRun).start();
    }

    private void handleMessage(Message msg) {
        hideProgressBar();
        rechargeBtn.setEnabled(true);
        switch (msg.what) {
            case PAY_AL:
                AliPayResult payResult = new AliPayResult((String) msg.obj);
                // 支付宝返回此次支付结果及加签，建议对支付宝签名信息拿签约时支付宝提供的公钥做验签
                String memo = payResult.getMemo();// 提示信息【可空，保留参数，一般无内容】
                String result = payResult.getResult();// 本次操作返回的结果数据【不可空】
                String resultStatus = payResult.getResultStatus();// 状态代码【不可空】
                LogUtil.print("aliPayResult--->resultStatus=" + resultStatus);
                LogUtil.print("aliPayResult--->result=" + result);
                LogUtil.print("aliPayResult--->memo=" + memo);
                // 判断resultStatus为“9000”则代表支付成功
                switch (resultStatus) {
                    case "9000":// 订单支付成功
                    case "8000":// 正在处理中【支付结果因为支付渠道原因或者系统原因还在等待支付结果确认，最终交易是否成功以服务端异步通知为准（小概率状态）】
                        ToastUtil.makeTextShort("支付成功");
                        onRecharge();
                        break;
                    case "6001":// 用户中途取消
                        ToastUtil.makeTextShort("取消支付");
                        payFailure(PAY_CANCEL);
                        break;
                    default: // 订单支付失败【4000】、网络连接出错【6002】
                        ToastUtil.makeTextShort("支付失败");
                        payFailure(PAY_FAILURE);
                        break;
                }
                break;
            case PAY_UP:
                if (msg.obj == null || ((String) msg.obj).length() == 0) {
                    showTipDialog("错误提示", "网络连接失败,请重试!");
                } else {
                    LogUtil.print("UPPAY -- tn::" + msg.obj);
                    /**
                     * 【银联支付】步骤2：通过银联工具类启动支付插件
                     */
                    UPPayAssistEx.startPay(RechargeActivity.this, null, null, (String) msg.obj, mMode);
                }
                break;
            case PAY_WX:
                try{
                    if (msg.obj == null || ((String) msg.obj).length() == 0) {
                        String content = (String) msg.obj;
                        Log.e("get server pay params:", content);
                        JSONObject json = new JSONObject(content);
                        if(!json.has("retcode") ){
                            PayReq req = new PayReq();
                            //req.appId = "wxf8b4f85f3a794e77";  // 测试用appId
                            req.appId			= json.getString("appid");
                            req.partnerId		= json.getString("partnerid");
                            req.prepayId		= json.getString("prepayid");
                            req.nonceStr		= json.getString("noncestr");
                            req.timeStamp		= json.getString("timestamp");
                            req.packageValue	= json.getString("package");
                            req.sign			= json.getString("sign");
                            req.extData			= "app data"; // optional
                            Toast.makeText(this, "正常调起支付", Toast.LENGTH_SHORT).show();
                            // 在支付之前，如果应用没有注册到微信，应该先调用IWXMsg.registerApp将应用注册到微信
                            boolean success = wxAPI.sendReq(req);
                            if (success) {
                                onRecharge();
                            } else {
                                payFailure(PAY_FAILURE);
                            }
                        }else{
                            LogUtil.error("PAY_GET", "返回错误"+json.getString("retmsg"));
                            ToastUtil.makeTextShort("返回错误"+json.getString("retmsg"));
                            payFailure(PAY_FAILURE);
                        }
                    }else{
                        LogUtil.error("PAY_GET", "服务器请求错误");
                        ToastUtil.makeTextShort("服务器请求错误");
                        payFailure(PAY_FAILURE);
                    }
                }catch (Exception e) {
                    e.printStackTrace();
                    LogUtil.error("PAY_GET", "异常："+e.getMessage());
                    ToastUtil.makeTextShort("异常："+e.getMessage());
                    payFailure(PAY_FAILURE);
                }
                break;
        }
    }

    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        /**
         * 【银联支付】步骤3：处理银联手机支付控件返回的支付结果
         */
        if (data == null)
            return;
        // 支付控件返回字符串:success、fail、cancel 分别代表支付成功，支付失败，支付取消
        String str = data.getExtras().getString("pay_result");
        LogUtil.print("unionPay -- result=" + data.getExtras().toString());
        if ("success".equalsIgnoreCase(str)) {
            // 支付成功后，extra中如果存在result_data，取出校验
            // result_data结构见c）result_data参数说明
            if (data.hasExtra("result_data")) {
                String result = data.getExtras().getString("result_data");
                try {
                    JSONObject resultJson = new JSONObject(result);
                    String sign = resultJson.getString("sign");
                    String dataOrg = resultJson.getString("data");
                    // 验签证书同后台验签证书
                    // 此处的verify，商户需送去商户后台做验签
                    boolean ret = RSAUtil.verify(dataOrg, sign, mMode);
                    if (ret) {
                        // 验证通过后，显示支付结果
                        onRecharge();
                    } else {
                        // 验证不通过后的处理
                        // 建议通过商户后台查询支付结果
                        payFailure(PAY_FAILURE);
                    }
                } catch (JSONException e) {
                    e.printStackTrace();
                }
            } else {
                // 未收到签名信息
                // 建议通过商户后台查询支付结果
                onRecharge();
            }
        } else if ("fail".equalsIgnoreCase(str)) {
            payFailure(PAY_FAILURE);
        } else if ("cancel".equalsIgnoreCase(str)) {
            payFailure(PAY_CANCEL);
        }
    }

    private void onRecharge(){
        showProgressBar();
        RechargeParams params = new RechargeParams();
        params.userId = UserUtil.getUserId();
        params.method = payMethod;
        mPresenter.onRecharge(params);
    }

    private void payFailure(String payStatus){
        if (PAY_CANCEL.equals(payStatus)) {
            showTipDialog("支付取消", "您取消了此次交易的支付");
        } else {
            showTipDialog("支付失败", "此次交易支付失败");
        }
    }

    private void showTipDialog(String title, String msg){
        DialogUtil.showConfirmDialog(this, title, msg, null);
    }


    public static class PayHandler extends Handler {
        WeakReference<RechargeActivity> wrf;

        public PayHandler(RechargeActivity activity) {
            this.wrf = new WeakReference<>(activity);
        }

        @Override
        public void handleMessage(Message msg) {
            RechargeActivity activity = wrf.get();
            if (activity != null) {
                activity.handleMessage(msg);
            }
        }
    }
}
